import { useState, useEffect, useCallback, useRef } from 'react';

    // WebSocket服务器URL配置
    const WS_URL = process.env.NODE_ENV === 'production' 
      ? 'wss://api.example.com/ws' 
      : 'ws://localhost:5000/ws';

    /**
     * 自定义Hook，用于处理WebSocket连接
     * @param {string} namespace - 可选的命名空间
     * @param {Object} options - 配置选项
     * @returns {Object} 包含WebSocket方法和状态的对象
     */
    const useSocket = (namespace = '', options = {}) => {
      const [isConnected, setIsConnected] = useState(false);
      const [error, setError] = useState(null);
      const [lastMessage, setLastMessage] = useState(null);
      
      const socketRef = useRef(null);
      const messageHandlersRef = useRef({});
      const reconnectTimeoutRef = useRef(null);
      
      const {
        autoConnect = true,
        reconnectAttempts = 5,
        reconnectInterval = 3000,
        onConnect = () => {},
        onDisconnect = () => {},
        onError = () => {},
      } = options;

      /**
       * 连接到WebSocket服务器
       */
      const connect = useCallback(() => {
        // 清除之前的重连定时器
        if (reconnectTimeoutRef.current) {
          clearTimeout(reconnectTimeoutRef.current);
          reconnectTimeoutRef.current = null;
        }

        // 如果已经连接，先关闭
        if (socketRef.current && (socketRef.current.readyState === WebSocket.OPEN || socketRef.current.readyState === WebSocket.CONNECTING)) {
          socketRef.current.close();
        }

        try {
          // 构建WebSocket URL
          const url = namespace ? `${WS_URL}/${namespace}` : WS_URL;
          
          // 添加token（如果有）
          const token = localStorage.getItem('authToken');
          const wsUrl = token ? `${url}?token=${token}` : url;
          
          // 创建WebSocket连接
          socketRef.current = new WebSocket(wsUrl);
          
          // 设置事件处理器
          socketRef.current.onopen = () => {
            setIsConnected(true);
            setError(null);
            onConnect();
          };
          
          socketRef.current.onclose = (event) => {
            setIsConnected(false);
            onDisconnect(event);
          };
          
          socketRef.current.onerror = (event) => {
            setError('WebSocket连接错误');
            onError(event);
          };
          
          socketRef.current.onmessage = (event) => {
            try {
              const data = JSON.parse(event.data);
              setLastMessage(data);
              
              // 调用对应事件类型的处理函数
              if (data.type && messageHandlersRef.current[data.type]) {
                messageHandlersRef.current[data.type].forEach(handler => handler(data));
              }
              
              // 调用通用消息处理函数
              if (messageHandlersRef.current['*']) {
                messageHandlersRef.current['*'].forEach(handler => handler(data));
              }
            } catch (err) {
              console.error('解析WebSocket消息时出错:', err);
            }
          };
        } catch (err) {
          setError(err.message || 'WebSocket连接失败');
          console.error('WebSocket连接失败:', err);
        }
      }, [namespace, onConnect, onDisconnect, onError]);

      /**
       * 重新连接WebSocket
       * @param {number} attempt - 当前尝试次数
       */
      const reconnect = useCallback((attempt = 0) => {
        if (attempt < reconnectAttempts) {
          reconnectTimeoutRef.current = setTimeout(() => {
            console.log(`尝试重新连接WebSocket (${attempt + 1}/${reconnectAttempts})...`);
            connect();
            
            // 如果连接失败，继续尝试
            if (!isConnected) {
              reconnect(attempt + 1);
            }
          }, reconnectInterval);
        } else {
          setError('WebSocket重连失败，已达到最大尝试次数');
        }
      }, [connect, isConnected, reconnectAttempts, reconnectInterval]);

      /**
       * 发送消息到WebSocket服务器
       * @param {string} type - 消息类型
       * @param {Object} data - 消息数据
       * @returns {boolean} 是否发送成功
       */
      const send = useCallback((type, data = {}) => {
        if (socketRef.current && socketRef.current.readyState === WebSocket.OPEN) {
          const message = JSON.stringify({
            type,
            ...data,
            timestamp: new Date().toISOString(),
          });
          
          socketRef.current.send(message);
          return true;
        } else {
          console.error('WebSocket未连接，无法发送消息');
          return false;
        }
      }, []);

      /**
       * 添加消息处理函数
       * @param {string} type - 消息类型，使用'*'表示处理所有消息
       * @param {Function} handler - 处理函数
       * @returns {Function} 用于移除处理函数的函数
       */
      const on = useCallback((type, handler) => {
        if (!messageHandlersRef.current[type]) {
          messageHandlersRef.current[type] = [];
        }
        
        messageHandlersRef.current[type].push(handler);
        
        // 返回一个函数，用于移除此处理函数
        return () => {
          messageHandlersRef.current[type] = messageHandlersRef.current[type].filter(h => h !== handler);
          if (messageHandlersRef.current[type].length === 0) {
            delete messageHandlersRef.current[type];
          }
        };
      }, []);

      /**
       * 断开WebSocket连接
       */
      const disconnect = useCallback(() => {
        if (socketRef.current) {
          socketRef.current.close();
          socketRef.current = null;
        }
        
        if (reconnectTimeoutRef.current) {
          clearTimeout(reconnectTimeoutRef.current);
          reconnectTimeoutRef.current = null;
        }
        
        setIsConnected(false);
      }, []);

      // 初始连接
      useEffect(() => {
        if (autoConnect) {
          connect();
        }
        
        // 清理函数
        return () => {
          disconnect();
        };
      }, [autoConnect, connect, disconnect]);

      // 监听连接状态，在断开时尝试重连
      useEffect(() => {
        if (!isConnected && autoConnect && socketRef.current) {
          reconnect();
        }
      }, [isConnected, autoConnect, reconnect]);

      return {
        isConnected,
        error,
        lastMessage,
        connect,
        disconnect,
        send,
        on,
      };
    };

    export default useSocket;
